package asteroids.model.programs;

import java.util.ArrayList;
import java.util.HashMap;

import exception.StopActionClassException;

import asteroids.model.Ship;
import asteroids.model.programs.Kind.KindOfExpression;
import asteroids.model.programs.statements.Statement;
import be.kuleuven.cs.som.annotate.*;

@SuppressWarnings("rawtypes")
public class Program {
	
	public Program(HashMap<String,Kind> globals,Statement statement){
		setGlobals(globals);
		this.mainSequence = statement;
	}
 
	public void execute(double dt){
		Statement main = getMainSequence();
		this.times = Math.round(dt/0.2);
		for(int i=0; i<times; i++){
		try{
		main.execute(this);
		main.reset();
		main.execute(this);
		}
		catch(StopActionClassException exc){
		}
		}
	}
	
	@Basic
	public  HashMap<String, Global> getGlobals(){
		return this.globals;
	}
	
	public void setGlobals(HashMap<String,Kind> globals){
		ArrayList<String> names = new ArrayList<String>(globals.keySet());
		for(String name: names){
			Kind kind = globals.get(name);
			if(kind.getKind() == KindOfExpression.Double)
				this.globals.put(name,new Global<Double>(name,new Double(0)));
			if(kind.getKind() == KindOfExpression.Entity)
				this.globals.put(name, new Global<Literal<?>>(name,null));
			if(kind.getKind()== KindOfExpression.Boolean){
				this.globals.put(name,new Global<Boolean>(name,true));
			}
		}
	}
	
	private long times;
	
	private HashMap<String,Global> globals = new HashMap<String,Global>();
	
	@Basic @Immutable
	public Statement getMainSequence(){
		return this.mainSequence;
	}
	
	private Statement mainSequence;
	
	@Basic
	public Ship getShip(){
		return this.ship;
	}
	
	public void setShip(Ship ship){
		this.ship = ship;
	}
	
	private Ship ship;
	

}
